home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Turnbull China Bikeride
/
Turnbull China Bikeride - Disc 1.iso
/
ARGONET
/
PD
/
GRAPHICS
/
GIF2RPC.SPK
/
source
/
16bpp_66bit
/
c
/
fsi
< prev
next >
Wrap
Text File
|
1995-10-16
|
4KB
|
122 lines
/* fsi.c
* AUTHOR: Cy Booker, cy@cheepnis.demon.co.uk
* LICENSE: FreeWare, Copyright (c) 1995 Cy Booker
*
* filter: * 7
* 3 5 1 (1/16)
*/
#include "internal.h"
#include <assert.h>
#include <string.h> /* memset() */
#include <stdlib.h> /* calloc() */
#include "OS:hourglass.h"
#include "OS:macros.h"
/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
*/
extern bool process_gif_16bpp_floyd_steinberg_66bit(
const process_gif *p) {
byte *rove;
int width, height;
int x, y;
const os_colour *palette;
int line_length;
int *buffer, *this_row, *next_row;
int buffer_width;
int r, g, b;
int or, og, ob;
int t;
int er, eg, eb;
int eblr, eblg, eblb;
int ebr, ebg, ebb;
assert(p);
assert(p->pixel_width > 0);
assert(p->pixel_height > 0);
assert(p->in_palette.colours);
/*
* floyd_steinberg requires storing error info for one pixel to right and one pixel to left
* so we will just allocate an extra column for each row and not do any edge checks
* each entry is stored as {r*SCALE, g*SCALE, b*SCALE}
*/
buffer_width = (p->pixel_width + 2) * 3;
buffer = calloc(1, sizeof(*buffer) * (buffer_width * 2));
if (!buffer) {
/*
* oh dear
*/
return TRUE;
}
initialise_scaling_tables();
/*
* not we pre-load values from the process_gif array
* because it considerably helps the compiler produce better code
*/
rove = p->buffer;
width = p->pixel_width;
height = p->pixel_height;
palette = p->in_palette.colours;
line_length = p->line_length;
for (y= height; (y > 0); y--) {
if ((y & 7) == 0) {
xhourglass_percentage((y * 100) / height);
}
this_row = buffer + (buffer_width * ((y + 2) % 2)) + 1*3; /* skip left hand 'dummy' column */
next_row = buffer + (buffer_width * ((y + 1) % 2)); /* point inside left hand dummy column */
memset(next_row, 0, sizeof(*next_row) * buffer_width);/* next row has no errors */
er = eg = eb = 0; /* error along this row */
/*
* note that just because we are actually scanning/outputting right to left
* doesn't matter as far as floyd_steinberg is concerned
* although it might help if we could ``snake''
*/
for (x= width - 1; (x >= 0); x--) {
INPUT;
r += *this_row++; /* add in errors from other row */
r += er; /* add in errors from this row */
g += *this_row++;
g += eg;
b += *this_row++;
b += eb;
PROCESS;
r -= or; /* error */
g -= og;
b -= ob;
er = (r * 7) / 16; /* diffuse pixel to `right' */
eg = (g * 7) / 16;
eb = (b * 7) / 16;
eblr = (r * 3) / 16; /* diffuse pixel `below left' */
eblg = (g * 3) / 16;
eblb = (b * 3) / 16;
*next_row += eblr; next_row++;
*next_row += eblg; next_row++;
*next_row += eblb; next_row++;
ebr = (r * 5) / 16; /* diffuse pixel `below' */
ebg = (g * 5) / 16;
ebb = (b * 5) / 16;
*next_row += ebr; next_row++;
*next_row += ebg; next_row++;
*next_row += ebb; next_row++;
*next_row += r - (er + eblr + ebr); next_row++; /* diffuse pixel `below right' */
*next_row += g - (eg + eblg + ebg); next_row++;
*next_row += b - (eb + eblb + ebb); next_row++;
next_row -= 3*2; /* adjust next_row pointer */
}
rove += line_length;
}
free(buffer);
return FALSE;
}